package com.hyst.utils;

import javax.crypto.Cipher;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;

/***
 * @Des: RSA加密
 * @Author: jiyang
 * @Date: 2018-10-26 14:36
 */
public class RSAUtil {

    private final static String PUBLIC_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKgw2UJlI+XJTQTbvc7H9+xESMP8J7pbNXf9AvpR3xwHslg3ftKzoIqOhKjcOOgajWxEq4oGnrv95yPIFT6l/PsCAwEAAQ==";

    private final static String PRIVATE_KEY = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAqDDZQmUj5clNBNu9zsf37ERIw/wnuls1d/0C+lHfHAeyWDd+0rOgio6EqNw46BqNbESrigaeu/3nI8gVPqX8+wIDAQABAkBObNCxq/WMLUxTip8773SEX+bKNCbWN7d75qdfz5NIPvDt7bl0VQ/n2mBgr4srQI3SjstypQRdkB6oWpuJJd0RAiEA1SqeIRNz9M3M2X4sDMNyvTNnNT0ZPRWUvAM9fMY12bkCIQDJ/KmDqXasffMzh+klscW8ed4F+Y2YlUZ5+mOkcY6WUwIgOEerPkJbkBux5Q5p5OjJZ2il7Cl4e2cyQL1+Q241k4kCIQCjk1xsZcbXtkBIUR69ChTKqB7n08uZ7/ndOquLNvN0RQIhALR8RQh2SPj5SX71FVlD9pGa7243lPxgqZjBYTsIjVr7";

    /**
     * 公钥加密
     */
    public static String publicKeyEncodeRSA(String str) throws Exception{
        byte[] result = {};
        byte[] key = Base64.decodeBase64(PUBLIC_KEY.getBytes());
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        result = cipher.doFinal(str.getBytes());
        return new String(Base64.encodeBase64(result));
    }


    /**
     * 私钥解密
     */
    public static String privateKeyDecodeRSA(String str) throws Exception{
        byte[] result = {};
        byte[] key = Base64.decodeBase64(PRIVATE_KEY.getBytes());
        byte[] rsaStr = Base64.decodeBase64(str.getBytes());
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        result = cipher.doFinal(rsaStr);
        return new String(result);
    }


    // jdk实现：
    public static void jdkRSA() {
        try {
            // 1.初始化发送方密钥
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
            System.out.println("Public Key:" + new String(Base64.encodeBase64(rsaPublicKey.getEncoded())));
            System.out.println("Private Key:" + new String(Base64.encodeBase64(rsaPrivateKey.getEncoded())));

            // 2.私钥加密、公钥解密 ---- 加密
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            byte[] result = cipher.doFinal("rsa test".getBytes());
            System.out.println("私钥加密、公钥解密 ---- 加密:" + new String(Base64.encodeBase64(result)));

            // 3.私钥加密、公钥解密 ---- 解密
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            result = cipher.doFinal(result);
            System.out.println("私钥加密、公钥解密 ---- 解密:" + new String(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 加密
    public static String base64Encode(String str) {
        byte[] b = null;
        String s = null;
        try {
            b = str.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (b != null) {
            s = new BASE64Encoder().encode(b);
        }
        return s;
    }

    /**
     * Encodes a string 2 MD5
     *
     * @param str String to encode
     * @return Encoded String
     * @throws NoSuchAlgorithmException
     */
    public static String crypt(String str) {
        if (str == null || str.length() == 0) {
            throw new IllegalArgumentException("String to encript cannot be null or zero length");
        }
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] hash = md.digest();
            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }

    public static void main(String[] args) throws Exception {
        //827ccb0eea8a706c4c34a16891f84e7b
        System.out.println(crypt("123456"));
//        jdkRSA();
//        System.out.println(publicKeyEncodeRSA("123456"));
//        System.out.println(privateKeyDecodeRSA("j4M2mGb9mJOXoR3VHAWZ4+jZP7NhJ4L1HpqTiup4UlcVctmKGKFRdg3bvUCnSpjUQN1ZTULFsnVEMA8zK56Avw=="));
//
//        System.out.println(base64Encode("123456"));
//        System.out.println("VUNuU3BqVVFOMVpUVUxGc25WRU1BOHpLNTZBdnc9PQ==".length());
    }

}
